package top.continew.admin.generator.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.continew.admin.common.config.properties.WxMaProperties;
import top.continew.admin.common.context.UserContextHolder;
import top.continew.admin.generator.mapper.TaskTodoMapper;
import top.continew.admin.generator.model.entity.ProvinceLeadersDO;
import top.continew.admin.generator.model.entity.TaskTodoDO;
import top.continew.admin.generator.model.entity.TaskTodoUploadDO;
import top.continew.admin.generator.model.query.ProvinceLeadersQuery;
import top.continew.admin.generator.model.query.TaskTodoQuery;
import top.continew.admin.generator.model.req.TaskTodoReq;
import top.continew.admin.generator.model.resp.TaskTodoDetailResp;
import top.continew.admin.generator.model.resp.TaskTodoResp;
import top.continew.admin.generator.model.resp.TaskTodoUploadResp;
import top.continew.admin.generator.service.ProvinceLeadersService;
import top.continew.admin.generator.service.TaskTodoService;
import top.continew.admin.generator.service.TaskTodoUploadService;
import top.continew.admin.generator.service.TaskListService;
import top.continew.admin.generator.service.TaskTransferService;
import top.continew.admin.generator.model.resp.TaskListDetailResp;
import top.continew.admin.generator.model.resp.TransferChainResp;
import top.continew.admin.open.model.req.WxSubscribeMessageReq;
import top.continew.admin.open.service.NotifyService;
import top.continew.admin.system.model.entity.user.UserDO;
import top.continew.admin.system.model.req.ProcessTodoReq;
import top.continew.admin.system.model.resp.TaskTodoExportRes;
import top.continew.admin.system.service.UserService;
import top.continew.starter.extension.crud.service.BaseServiceImpl;
import top.continew.starter.extension.crud.model.resp.PageResp;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 待办事项业务实现
 *
 * @author kellen
 * @since 2025/07/30
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TaskTodoServiceImpl extends BaseServiceImpl<TaskTodoMapper, TaskTodoDO, TaskTodoResp, TaskTodoDetailResp, TaskTodoQuery, TaskTodoReq> implements TaskTodoService {

    private final TaskTodoUploadService taskTodoUploadService;
    private final UserService userService;
    private final NotifyService notifyService;
    private final WxMaProperties wxMaProperties;
    private final ProvinceLeadersService provinceLeadersService;
    private final TaskListService taskListService;
    private final TaskTransferService taskTransferService;


    @Override
    protected void beforeCreate(TaskTodoReq req) {
        req.setTaskType(0); // 默认待办类型
        req.setTaskStatus(0); // 默认待查看状态
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    protected void afterCreate(TaskTodoReq req, TaskTodoDO entity) {
        // 保存附件
        if (req.getAttachments() != null && !req.getAttachments().isEmpty()) {
            List<TaskTodoUploadDO> uploads = req.getAttachments().stream()
                    .map(attachment -> {
                        TaskTodoUploadDO upload = new TaskTodoUploadDO();
                        upload.setTaskTodoId(entity.getId());
                        upload.setBelongTo(0); // 0-发布者
                        upload.setFileName(attachment.getFileName());
                        upload.setUploadUrl(attachment.getFileUrl());
                        return upload;
                    })
                    .collect(Collectors.toList());
            taskTodoUploadService.saveBatch(uploads);
        }
        
        // 推送微信消息给负责人
        pushWxMsgToDirector(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    protected void afterUpdate(TaskTodoReq req, TaskTodoDO entity) {
        // 删除原有发布者附件
        taskTodoUploadService.remove(
                new LambdaQueryWrapper<TaskTodoUploadDO>()
                        .eq(TaskTodoUploadDO::getTaskTodoId, entity.getId())
                        .eq(TaskTodoUploadDO::getBelongTo, 0)
        );
        
        // 保存新附件
        if (req.getAttachments() != null && !req.getAttachments().isEmpty()) {
            List<TaskTodoUploadDO> uploads = req.getAttachments().stream()
                    .map(attachment -> {
                        TaskTodoUploadDO upload = new TaskTodoUploadDO();
                        upload.setTaskTodoId(entity.getId());
                        upload.setBelongTo(0); // 0-发布者
                        upload.setFileName(attachment.getFileName());
                        upload.setUploadUrl(attachment.getFileUrl());
                        return upload;
                    })
                    .collect(Collectors.toList());
            taskTodoUploadService.saveBatch(uploads);
        }
    }

    @Override
    public List<Object> getUserList() {
        List<ProvinceLeadersDO> leadersDOS = provinceLeadersService.list();
        List<UserDO> users = userService.list(new LambdaQueryWrapper<UserDO>().eq(UserDO::getStatus, 1).in(UserDO::getId,leadersDOS.stream().map(ProvinceLeadersDO::getUserId).collect(Collectors.toSet())));
        return users.stream()
                .map(user -> {
                    Map<String, Object> userInfo = new HashMap<>();
                    userInfo.put("id", user.getId());
                    userInfo.put("nickname", user.getNickname());
                    userInfo.put("username", user.getUsername());
                    Integer subscribeCount=user.getSubscribeCount();
                    if(user.getSubscribeCount()==null|| user.getSubscribeCount()<0){
                        subscribeCount=0;
                    }
                    userInfo.put("subscribeCount", subscribeCount);
                    return userInfo;
                })
                .collect(Collectors.toList());
    }

    /**
     * 获取待办事项统计
     */
    public Map<String, Object> getTaskTodoStats(Long userId) {
        Map<String, Object> stats = new HashMap<>();
        
        // 总数
        long total = count(new LambdaQueryWrapper<TaskTodoDO>()
                .eq(TaskTodoDO::getDirectorId, userId));
        
        // 待查看
        long pending = count(new LambdaQueryWrapper<TaskTodoDO>()
                .eq(TaskTodoDO::getDirectorId, userId)
                .eq(TaskTodoDO::getTaskStatus, 0));
        
        // 已查看
        long viewed = count(new LambdaQueryWrapper<TaskTodoDO>()
                .eq(TaskTodoDO::getDirectorId, userId)
                .eq(TaskTodoDO::getTaskStatus, 1));
        
        // 已处理
        long processed = count(new LambdaQueryWrapper<TaskTodoDO>()
                .eq(TaskTodoDO::getDirectorId, userId)
                .eq(TaskTodoDO::getTaskStatus, 2));
        
        stats.put("total", total);
        stats.put("pending", pending);
        stats.put("viewed", viewed);
        stats.put("processed", processed);
        
        return stats;
    }

    protected void fillResp(TaskTodoResp resp, TaskTodoDO entity) {
        // 填充负责人名字
        UserDO director = userService.getById(entity.getDirectorId());
        if (director != null) {
            resp.setDirectorName(director.getNickname());
        }

        // 填充状态描述
        resp.setTaskStatusDesc(getTaskStatusDesc(entity.getTaskStatus()));
    }

    protected void fillListResp(TaskTodoResp resp, TaskTodoDO entity) {
        fillResp(resp, entity);
    }

    protected TaskTodoResp toListResp(TaskTodoDO entity) {
        TaskTodoResp resp = new TaskTodoResp();
        BeanUtils.copyProperties(entity, resp);
        fillResp(resp, entity);
        return resp;
    }



    /**
     * 分页查询待办事项列表
     */
    @Override
    public PageResp<TaskTodoResp> pageTaskTodo(Integer page, Integer size, String taskContent, Integer taskStatus, Long directorId) {
        LambdaQueryWrapper<TaskTodoDO> wrapper = new LambdaQueryWrapper<TaskTodoDO>()
                .like(taskContent != null, TaskTodoDO::getTaskContent, taskContent)
                .eq(taskStatus != null, TaskTodoDO::getTaskStatus, taskStatus)
                .eq(directorId != null, TaskTodoDO::getDirectorId, directorId)
                .orderByDesc(TaskTodoDO::getCreateTime);
        
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<TaskTodoDO> pageParam = 
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size);
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<TaskTodoDO> pageResult = page(pageParam, wrapper);
        
        List<TaskTodoResp> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(pageResult.getRecords())) {
            // 批量查询用户信息
            Set<Long> directorIds = pageResult.getRecords().stream()
                    .map(TaskTodoDO::getDirectorId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            
            Map<Long, UserDO> userMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(directorIds)) {
                List<UserDO> users = userService.listByIds(directorIds);
                userMap = users.stream().collect(Collectors.toMap(UserDO::getId, user -> user));
            }
            
            // 批量填充数据
            final Map<Long, UserDO> finalUserMap = userMap;
            list = pageResult.getRecords().stream().map(entity -> {
                TaskTodoResp resp = new TaskTodoResp();
                BeanUtils.copyProperties(entity, resp);
                
                // 填充负责人名字
                UserDO director = finalUserMap.get(entity.getDirectorId());
                if (director != null) {
                    resp.setDirectorName(director.getNickname());
                }
                
                // 填充状态描述
                resp.setTaskStatusDesc(getTaskStatusDesc(entity.getTaskStatus()));
                
                return resp;
            }).collect(Collectors.toList());
        }
        
        PageResp<TaskTodoResp> result = new PageResp<>();
        result.setList(list);
        result.setTotal(pageResult.getTotal());
        return result;
    }

    /**
     * 获取我的待办事项列表
     */
    @Override
    public PageResp<TaskTodoResp> getMyTodoList(Long userId, Integer page, Integer size, List<Integer> status) {
        LambdaQueryWrapper<TaskTodoDO> wrapper = new LambdaQueryWrapper<TaskTodoDO>()
                .eq(TaskTodoDO::getDirectorId, userId)
                .in(CollectionUtils.isNotEmpty(status), TaskTodoDO::getTaskStatus, status)
                .orderByDesc(TaskTodoDO::getCreateTime);
        
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<TaskTodoDO> pageParam = 
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size);
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<TaskTodoDO> pageResult = page(pageParam, wrapper);
        
        List<TaskTodoResp> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(pageResult.getRecords())) {
            // 批量查询用户信息
            Set<Long> directorIds = pageResult.getRecords().stream()
                    .map(TaskTodoDO::getDirectorId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            
            Map<Long, UserDO> userMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(directorIds)) {
                List<UserDO> users = userService.listByIds(directorIds);
                userMap = users.stream().collect(Collectors.toMap(UserDO::getId, user -> user));
            }
            
            // 批量填充数据
            final Map<Long, UserDO> finalUserMap = userMap;
            list = pageResult.getRecords().stream().map(entity -> {
                TaskTodoResp resp = new TaskTodoResp();
                BeanUtils.copyProperties(entity, resp);
                
                // 填充负责人名字
                UserDO director = finalUserMap.get(entity.getDirectorId());
                if (director != null) {
                    resp.setDirectorName(director.getNickname());
                }
                
                // 填充状态描述
                resp.setTaskStatusDesc(getTaskStatusDesc(entity.getTaskStatus()));
                
                return resp;
            }).collect(Collectors.toList());
        }
        
        PageResp<TaskTodoResp> result = new PageResp<>();
        result.setList(list);
        result.setTotal(pageResult.getTotal());
        return result;
    }

    /**
     * 获取待办事项详情
     */
    @Override
    public TaskTodoDetailResp getTodoDetail(Long id) {
        TaskTodoDetailResp taskTodoDetailResp = get(id);
        if(taskTodoDetailResp.getTaskStatus().equals(0)){
            TaskTodoDO updateEntity = new TaskTodoDO();
            updateEntity.setId(id);
            updateEntity.setTaskStatus(1);
            updateEntity.setUpdateTime(LocalDateTime.now());
            getBaseMapper().updateById(updateEntity);
            taskTodoDetailResp.setTaskStatus(updateEntity.getTaskStatus());
        }
        return taskTodoDetailResp;
    }

    /**
     * 处理待办事项
     */
    @Override
    public void processTodo(ProcessTodoReq reqObj) {
        // 这里需要将Object转换为具体的请求对象
        // 由于ApiController中的ProcessTodoReq是内部类，这里简化处理
        Long id = reqObj.getId();
        Integer status = reqObj.getStatus();
        String notes = reqObj.getNotes();
        List<ProcessTodoReq.AttachmentInfo> attachments = reqObj.getAttachments();

        TaskTodoDO taskTodo = getById(id);
        if (taskTodo == null) {
            throw new RuntimeException("待办事项不存在");
        }
        taskTodo.setNeedSample(null!=reqObj.getNeedSample() && reqObj.getNeedSample()?1:0);
        taskTodo.setMailingAddress(reqObj.getMailingAddress());
        taskTodo.setTaskStatus(status);
        updateById(taskTodo);
        
        // 如果有附件，保存处理者附件
        if (attachments != null && !attachments.isEmpty()) {
            List<TaskTodoUploadDO> uploads = attachments.stream()
                    .map(attachment -> {
                        TaskTodoUploadDO upload = new TaskTodoUploadDO();
                        upload.setTaskTodoId(id);
                        upload.setBelongTo(1); // 1-处理者
                        upload.setFileName(attachment.getFileName());
                        upload.setUploadUrl(attachment.getFileUrl());
                        return upload;
                    })
                    .collect(Collectors.toList());
            taskTodoUploadService.saveBatch(uploads);
        }
    }

    /**
     * 获取用户的待办事项列表
     */
    public List<TaskTodoResp> getUserTaskTodoList(Long userId, Integer status) {
        LambdaQueryWrapper<TaskTodoDO> wrapper = new LambdaQueryWrapper<TaskTodoDO>()
                .eq(TaskTodoDO::getDirectorId, userId)
                .orderByDesc(TaskTodoDO::getCreateTime);
        
        if (status != null) {
            wrapper.eq(TaskTodoDO::getTaskStatus, status);
        }
        
        List<TaskTodoDO> list = list(wrapper);
        return list.stream().map(td->{
            TaskTodoResp taskTodoResp = new TaskTodoResp();
            BeanUtils.copyProperties(td, taskTodoResp);
            fillResp(taskTodoResp, td);
            return taskTodoResp;
        }).toList();
    }

    /**
     * 更新待办事项状态
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateTaskStatus(Long id, Integer status, List<TaskTodoReq.AttachmentInfo> attachments) {
        TaskTodoDO taskTodo = getById(id);
        if (taskTodo == null) {
            throw new RuntimeException("待办事项不存在");
        }
        
        taskTodo.setTaskStatus(status);
        updateById(taskTodo);
        
        // 如果有附件，保存处理者附件
        if (attachments != null && !attachments.isEmpty()) {
            List<TaskTodoUploadDO> uploads = attachments.stream()
                    .map(attachment -> {
                        TaskTodoUploadDO upload = new TaskTodoUploadDO();
                        upload.setTaskTodoId(id);
                        upload.setBelongTo(1); // 1-处理者
                        upload.setFileName(attachment.getFileName());
                        upload.setUploadUrl(attachment.getFileUrl());
                        return upload;
                    })
                    .collect(Collectors.toList());
            taskTodoUploadService.saveBatch(uploads);
        }
    }

    /**
     * 推送微信消息给负责人
     */
    private void pushWxMsgToDirector(TaskTodoDO taskTodo) {
        try {
            UserDO director = userService.getById(taskTodo.getDirectorId());
            if (director == null || StrUtil.isBlank(director.getOpenId())) {
                log.warn("负责人 {} openId为空，无法推送微信消息", taskTodo.getDirectorId());
                return;
            }

            WxSubscribeMessageReq params = new WxSubscribeMessageReq();
            params.setOpenId(director.getOpenId());
            params.setPageUrl(wxMaProperties.getConfigs().get(0).getPageUrl());
            params.setTemplateId(wxMaProperties.getConfigs().get(0).getTemplateId());
            
            Map<String, String> content = new HashMap<>();
            content.put("thing4", DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd") + "待办");
            content.put("thing28", "待办事项");
            content.put("thing46", director.getNickname());
            content.put("thing1", getMaxLenStr(taskTodo.getTaskContent(), 15));
            content.put("thing3", "请及时处理");
            params.setMsgContent(content);
            
            notifyService.wxSubscribeMessage(params);
            log.info("已给负责人 {} 推送待办事项微信消息", director.getNickname());
        } catch (Exception e) {
            log.error("推送微信消息失败", e);
        }
    }

    @Override
    public TaskTodoDetailResp get(Long id) {
        TaskTodoDO entity = getById(id);
        if (entity == null) {
            return null;
        }
        
        TaskTodoDetailResp resp = new TaskTodoDetailResp();
        BeanUtils.copyProperties(entity, resp);
        resp.setTaskStatusDesc(getTaskStatusDesc(entity.getTaskStatus()));
        
        // 获取负责人姓名
        UserDO director = userService.getById(entity.getDirectorId());
        if (director != null) {
            resp.setDirectorName(director.getNickname());
        }
        
        // 加载附件信息
        List<TaskTodoUploadDO> uploads = taskTodoUploadService.list(
                new LambdaQueryWrapper<TaskTodoUploadDO>()
                        .eq(TaskTodoUploadDO::getTaskTodoId, id)
                        .orderByAsc(TaskTodoUploadDO::getBelongTo)
                        .orderByAsc(TaskTodoUploadDO::getCreateTime)
        );
        
        List<TaskTodoUploadResp> attachments = uploads.stream()
                .map(upload -> {
                    TaskTodoUploadResp uploadResp = new TaskTodoUploadResp();
                    BeanUtils.copyProperties(upload, uploadResp);
                    uploadResp.setIsImage(isImageFile(upload.getFileName()));
                    return uploadResp;
                })
                .collect(Collectors.toList());
        resp.setAttachments(attachments);
        
        // 加载关联任务信息
        if (entity.getTaskId() != null) {
            try {
                TaskListDetailResp taskDetail = taskListService.get(entity.getTaskId());
                resp.setRelatedTask(taskDetail);
                
                // 加载转派记录
                List<TransferChainResp> transferChain = taskTransferService.getTransferChain(entity.getTaskId());
                resp.setTransferRecords(transferChain);
            } catch (Exception e) {
                log.warn("加载关联任务信息失败: {}", e.getMessage());
            }
        }
        
        return resp;
    }

    /**
     * 获取任务状态描述
     */
    private String getTaskStatusDesc(Integer status) {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case 0: return "待查看";
            case 1: return "已查看";
            case 2: return "已处理";
            case 3: return "已关闭";
            default: return "未知";
        }
    }

    /**
     * 截取字符串最大长度
     */
    private String getMaxLenStr(String source, int len) {
        if (StrUtil.isBlank(source)) {
            return "";
        }
        return source.length() > len ? source.substring(0, len) : source;
    }

    /**
     * 判断文件是否为图片
     */
    private Boolean isImageFile(String fileName) {
        if (StrUtil.isBlank(fileName)) {
            return false;
        }
        String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        return "jpg".equals(extension) || "jpeg".equals(extension) || "png".equals(extension) || "gif".equals(extension) || "bmp".equals(extension) || "webp".equals(extension);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleTodoWithSample(top.continew.admin.generator.controller.TaskTodoController.HandleWithSampleReq req) {
        TaskTodoDO taskTodo = getById(req.getTodoId());
        if (taskTodo == null) {
            throw new RuntimeException("待办事项不存在");
        }
        
        // 更新状态和样品信息
        taskTodo.setTaskStatus(req.getStatus());
        taskTodo.setNeedSample(req.getNeedSample());
        if (req.getNeedSample() != null && req.getNeedSample() == 1) {
            if (StrUtil.isBlank(req.getMailingAddress())) {
                throw new RuntimeException("需要样品时必须填写邮寄地址");
            }
            taskTodo.setMailingAddress(req.getMailingAddress());
        }
        updateById(taskTodo);
        
        // 保存附件
        if (req.getAttachments() != null && !req.getAttachments().isEmpty()) {
            List<TaskTodoUploadDO> uploads = req.getAttachments().stream()
                    .map(attachment -> {
                        TaskTodoUploadDO upload = new TaskTodoUploadDO();
                        upload.setTaskTodoId(req.getTodoId());
                        upload.setBelongTo(1); // 1-处理者
                        upload.setFileName(attachment.getFileName());
                        upload.setUploadUrl(attachment.getFileUrl());
                        return upload;
                    })
                    .collect(Collectors.toList());
            taskTodoUploadService.saveBatch(uploads);
        }
    }

    @Override
    public void exportAllTodos(TaskTodoQuery query, jakarta.servlet.http.HttpServletResponse response) {
        try {
            // 构建查询条件
            LambdaQueryWrapper<TaskTodoDO> wrapper = new LambdaQueryWrapper<TaskTodoDO>()
                    .like(StrUtil.isNotBlank(query.getTaskContent()), TaskTodoDO::getTaskContent, query.getTaskContent())
                    .eq(query.getTaskStatus() != null, TaskTodoDO::getTaskStatus, query.getTaskStatus())
                    .eq(query.getDirectorId() != null, TaskTodoDO::getDirectorId, query.getDirectorId())
                    .orderByDesc(TaskTodoDO::getCreateTime);
            
            List<TaskTodoDO> todos = list(wrapper);
            List<TaskTodoExportRes> exportList=new ArrayList<>();
            if(CollectionUtils.isNotEmpty(todos)){
                List<UserDO> users = userService.list(new LambdaQueryWrapper<UserDO>().in(UserDO::getId, todos.stream().map(TaskTodoDO::getDirectorId).toList()));
                exportList = todos.stream().map(entity -> {
                    TaskTodoExportRes resp = new TaskTodoExportRes();
                    resp.setTaskContent(entity.getTaskContent());
                    if(null!=entity.getNeedSample()){
                        if(entity.getNeedSample().equals(0)){
                            resp.setNeedSample("否");
                        }else{
                            resp.setNeedSample("是");
                        }
                    }
                    resp.setMailingAddress(entity.getMailingAddress());
                    resp.setCreateTime(DateUtil.format(entity.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
                    Optional<UserDO> first = users.stream().filter(u -> u.getId().equals(entity.getDirectorId())).findFirst();
                    first.ifPresent(userDO -> resp.setDirectorName(userDO.getNickname()));
                    // 填充状态描述
                    resp.setTaskStatusDesc(getTaskStatusDesc(entity.getTaskStatus()));
                    return resp;
                }).collect(Collectors.toList());
            }

            
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = java.net.URLEncoder.encode("待办事项导出_" + DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss"), java.nio.charset.StandardCharsets.UTF_8).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=" + fileName + ".xlsx");
            
            com.alibaba.excel.EasyExcel.write(response.getOutputStream(), TaskTodoExportRes.class)
                    .sheet("待办事项")
                    .doWrite(exportList);
        } catch (Exception e) {
            log.error("导出待办事项失败", e);
        }
    }
    
    private List<List<String>> buildTodoExportHeaders() {
        return java.util.Arrays.asList(
                java.util.Arrays.asList("任务内容"),
                java.util.Arrays.asList("任务状态"),
                java.util.Arrays.asList("负责人"),
                java.util.Arrays.asList("是否需要样品"),
                java.util.Arrays.asList("邮寄地址"),
                java.util.Arrays.asList("创建时间")
        );
    }
}